home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / UUPC11QS.ARJ / SSLEEP.C < prev    next >
C/C++ Source or Header  |  1991-10-16  |  8KB  |  181 lines

  1. /*--------------------------------------------------------------------*/
  2. /*    s s l e e p . c                                                 */
  3. /*                                                                    */
  4. /*    Smart sleep routines for UUPC/extended                          */
  5. /*                                                                    */
  6. /*    Written by Dave Watts, modified by Drew Derbyshire              */
  7. /*                                                                    */
  8. /*    Generates DOS specific code with Windows support by default,    */
  9. /*    generates call to OS/2 family API if FAMILYAPI is defined       */
  10. /*--------------------------------------------------------------------*/
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <time.h>
  15. #include <dos.h>
  16.  
  17. #include "lib.h"
  18. #include "ssleep.h"
  19.  
  20. #ifdef FAMILYAPI
  21. #define INCL_NOPM
  22. #define INCL_BASE
  23. #include <os2.h>
  24. #include <assert.h>
  25. #else
  26. #include <sys/timeb.h>
  27. #define MULTIPLEX 0x2F
  28.  
  29. static void GiveUpTimeSlice(void);
  30. static int RunningUnderWindowsWith386(void);
  31.  
  32. /*--------------------------------------------------------------------*/
  33. /*              Use this first to see if the rest are OK              */
  34. /*                                                                    */
  35. /*                  MOV AX,1600h   ; Check for win386/win3.0          */
  36. /*                                   present                          */
  37. /*                  INT 2Fh                                           */
  38. /* Return AL = 0 -> No Windows, AL = 80 -> No WIn386 mode             */
  39. /*        AL = 1 or AL = FFh -> Win386 2.xx running                   */
  40. /*   else AL = Major version (3), AH = Minor version                  */
  41. /*--------------------------------------------------------------------*/
  42. /* --------------- Release time slice                                 */
  43. /*                  MOV AX,1680h   ; **** Release time slice          */
  44. /*                  INT 2Fh        ; Let someone else run             */
  45. /* Return code is AL = 80H -> service not installed, AL = 0 -> all    */
  46. /*                                                              OK    */
  47. /*--------------------------------------------------------------------*/
  48. /* --------------- Enter critical section (disable task switch)       */
  49. /*                  MOV AX,1681H   ; Don't tread on me!               */
  50. /*                  INT 2Fh                                           */
  51. /*--------------------------------------------------------------------*/
  52. /* --------------- End critical section (Permit task switching)       */
  53. /*                  MOV AX,1682h                                      */
  54. /*                  INT 2Fh                                           */
  55. /*--------------------------------------------------------------------*/
  56.  
  57. /*--------------------------------------------------------------------*/
  58. /*    R u n n i n g U n d e r W i n d o w s W i t h 3 8 6             */
  59. /*                                                                    */
  60. /*    Easily the longest function name in UUPC/extended.              */
  61. /*                                                                    */
  62. /*    Determines if we are running under MS-Windows 386 or            */
  63. /*    MS-Windows 3.  We save the result, to avoid excessively         */
  64. /*    disabling interrupts when in a spin loop.                       */
  65. /*--------------------------------------------------------------------*/
  66.  
  67. static int RunningUnderWindowsWith386(void)
  68. {
  69.    static int result = 2;
  70.    union REGS inregs, outregs;
  71.    int irq;
  72.  
  73.    if (result != 2)           /* First call?                         */
  74.       return result;          /* No --> Return saved result          */
  75.  
  76.    irq = MULTIPLEX;
  77.    inregs.x.ax = 0x1600;
  78.    int86(irq, &inregs, &outregs);
  79.    if ( (outregs.h.al & 0x7f) == 0)
  80.       result = 0;
  81.    else
  82.       result = 1;
  83.    return result;
  84. } /* RunningUnderWindowsWith386 */
  85.  
  86. /*--------------------------------------------------------------------*/
  87. /*    G i v e U p T i m e S l i c e                                   */
  88. /*                                                                    */
  89. /*    Surrender our time slice when executing under Windows/386       */
  90. /*    or Windows release 3.                                           */
  91. /*--------------------------------------------------------------------*/
  92.  
  93. static void GiveUpTimeSlice(void)
  94. {
  95.    union REGS inregs, outregs;
  96.    int irq = MULTIPLEX;
  97.  
  98.    inregs.x.ax = 0x1680;
  99.    int86(irq, &inregs, &outregs);
  100.    if (outregs.h.al != 0) {
  101.       printf("Problem giving up timeslice:  %u\n", outregs.h.al);
  102.       abort();
  103.    }
  104. } /* GiveUpTimeSlice */
  105. #endif
  106.  
  107.  
  108. /*--------------------------------------------------------------------*/
  109. /*    ssleep() - wait n seconds                                       */
  110. /*                                                                    */
  111. /*    Simply delay until n seconds have passed.                       */
  112. /*--------------------------------------------------------------------*/
  113.  
  114. void ssleep(time_t interval)
  115. {
  116.    time_t start;
  117.  
  118.    start = time((time_t *)NULL);
  119.    while ((time((time_t *)NULL) - start) < interval)
  120.       ddelay(1000);
  121. } /*ssleep*/
  122.  
  123. /*--------------------------------------------------------------------*/
  124. /*    d d e l a y                                                     */
  125. /*                                                                    */
  126. /*    Delay for an interval of milliseconds                           */
  127. /*--------------------------------------------------------------------*/
  128.  
  129. void   ddelay   (int milliseconds)
  130. {
  131.  
  132. #ifdef FAMILYAPI
  133.    USHORT result = DosSleep(milliseconds);
  134.    assert(result == 0);
  135. #else
  136.    struct timeb t;
  137.    time_t seconds;
  138.    unsigned last;
  139.  
  140. /*--------------------------------------------------------------------*/
  141. /*       Handle the special case of 0 delay, which is simply a        */
  142. /*                  request to give up our timeslice                  */
  143. /*--------------------------------------------------------------------*/
  144.  
  145.    if (milliseconds == 0)     /* Make it compatible with DosSleep    */
  146.    {
  147.       if (RunningUnderWindowsWith386())
  148.          GiveUpTimeSlice();
  149.       return;
  150.    } /* if */
  151.  
  152.    ftime(&t);                 /* Get a starting time                 */
  153.    last = t.millitm;          /* Save milliseconds portion           */
  154.    seconds = t.time;          /* Save seconds as well                */
  155.  
  156.    while( milliseconds > 0)   /* Begin the spin loop                 */
  157.    {
  158.       int volatile count;     /* Don't let compiler optimize this    */
  159.       if (RunningUnderWindowsWith386())
  160.          GiveUpTimeSlice();
  161.       else
  162.          for ( count = 0; count < 2400; count ++);
  163.                               /* We spin so that interrupts are
  164.                                  enabled for most of the loop        */
  165.       ftime(&t);              /* Take a new time check               */
  166.       if (t.time == seconds)  /* Same second as last pass?           */
  167.          milliseconds -= (t.millitm - last); /* Yes --> mSecond delta*/
  168.       else
  169.          milliseconds -= 1000 * (int) (t.time - seconds)
  170.                               - (last - t.millitm);
  171.                               /* No --> Handle wrap of mSeconds      */
  172.       last = t.millitm;       /* Update last tick indicator          */
  173.       seconds = t.time;       /* Update this as well; only needed if
  174.                                  it changed (see above), but it
  175.                                  kills time (which is our job)       */
  176.    } /* while */
  177.  
  178. #endif /* FAMILYAPI */
  179.  
  180. } /* ddelay */
  181.